#ifdef WIN32
#pragma once
#define WIN32_LEAN_AND_MEAN 
#define _WIN32_WINNT  0x0500
#endif

#include <map>
#include "ITouchListener.h"
#include <stdio.h>
#include <math.h>
#include <string>


#include "OscOutboundPacketStream.h"
#include "UdpSocket.h"


#define ADDRESS "127.0.0.1"
#define PORT 3333

#define OUTPUT_BUFFER_SIZE 4096


class SimpleOSCSender : public ITouchListener
{
public:
	std::string ip_address; 
	int port;

	SimpleOSCSender()
	{
		transmitSocket = NULL;
		ip_address = ADDRESS;
		port = PORT;
		connectSocket(ip_address, port);

	}

	~SimpleOSCSender()
	{
		delete transmitSocket;
	}

	// Set IP and Port with commandline parameters
	void connectSocket(std::string ip_address, int port)
	{			
		transmitSocket = new UdpTransmitSocket( IpEndpointName( ip_address.c_str(), port ) );
		printf("using ip:%s port:%i\n\n", ip_address.c_str(), port);
		frameSeq = 0;
	}

	//! Notify that a finger has just been made active. 
	virtual void fingerDown(TouchData data)
	{

		fingerList[data.ID] = data;

		
		//printf("Press detected: %d %f, %f\n", data.ID, data.X, data.Y);

	}

	//! Notify that a finger has moved 
	virtual void fingerUpdate(TouchData data)
	{

		fingerList[data.ID] = data;
		//printf("Update Event: %d %f, %f\n", data.ID, data.X, data.Y);

	}

	//! A finger is no longer active..
	virtual void fingerUp(TouchData data)
	{
		std::map<int, TouchData>::iterator iter;


		for(iter=fingerList.begin(); iter != fingerList.end(); iter++)
		{
			if(iter->second.ID == data.ID)
			{
				fingerList.erase(iter);
				//printf("Up Event: %d %f, %f\n", data.ID, data.X, data.Y);
				return;
			}
		}
	}

	void frame()
	{
		if(!transmitSocket)
			return;

		// send update messages..

		char buffer[OUTPUT_BUFFER_SIZE];
		osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );
		std::map<int, TouchData>::iterator iter1, iter2, iter_last;	    

		//if(fingerList.size() > 0)
		//{	    
			p.Clear();
			iter1=fingerList.begin();
			p << osc::BeginBundleImmediate;
			p << osc::BeginMessage( "/blobs");			


				for(; iter1 != fingerList.end(); iter1++)
				{
					TouchData d = (*iter1).second;
						p << (float) (d.X - 0.5) << (float) (d.Y - 0.5) << (float) d.ID << (float) (0.2 * d.width);
				}

			
			p << osc::EndMessage;
			p << osc::EndBundle;


			if(p.IsReady())
				transmitSocket->Send( p.Data(), p.Size() );


		//}

	}

	void clearFingers()
	{
		fingerList.clear();
	}

private:
	UdpTransmitSocket *transmitSocket;

	// Keep track of all finger presses.
	std::map<int, TouchData> fingerList;
	int frameSeq;


};

